package com.itheima.manage.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.itheima.commons.constants.Constants;
import com.itheima.commons.pojo.domain.*;
import com.itheima.commons.pojo.entity.Log;
import com.itheima.commons.pojo.entity.PublishInfo;
import com.itheima.commons.pojo.entity.UserInfos;
import com.itheima.commons.pojo.entity.VideoInfo;
import com.itheima.commons.pojo.mongo.Comment;
import com.itheima.commons.pojo.mongo.Video;
import com.itheima.commons.vo.backstage.CommentsVo;
import com.itheima.commons.vo.backstage.PageResults;
import com.itheima.commons.vo.backstage.UserInfoMapVo;
import com.itheima.commons.vo.backstage.VideosVo;
import com.itheima.commons.vo.reception.PageResult;
import com.itheima.dubbo.interfaces.*;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author wds
 * @date 2021/12/18
 * @apiNote
 */
@Service
public class ManageUserService {
    @Reference
    ManageUserApi manageUserApi;

    @Reference
    UserLikeApi userLikeApi;

    @Reference
    VideoApi videoApi;

    @Autowired
    RedisTemplate redisTemplate;

    @Reference
    CommentApi commentApi;

    @Reference
    UserInfoApi userInfoApi;

    @Reference
    VideoInfoApi videoInfoApi;

    @Reference
    PublishInfoApi publishInfoApi;

    @Reference
    LogApi logApi;

    /**
     * 分页查询用户详细信息
     *
     * @param id       被查询用户id 模糊查询
     * @param nickname 昵称 模糊查询
     * @param city     注册城市
     * @param page     当前页码
     * @param pagesize 显示条数
     * @return
     */
    public PageResult queryUserInfoByIdAndNameAndCity(String id, String nickname, String city, Long page, Long pagesize) {
        //以上属性非必须 ，全为空则默认查询全部，结果按照最近活跃时间降序

        //先查询总的用户数量
        // Integer count = userInfoApi.queryUserInfoCount();

        //  !!!!!!!!!注意！！！！！
        //    ***  这里重写了一套个人信息查询mp  UserInfo----> UserInfos  **
        //！！！！！！！！！！！！！！
        // 1.查询Mysql数据库的用户个人信息表tb_user_info，用户账号表tb_user，用户冻结状态表tb_user_freeze，日志表
        List<UserInfos> userInfoList = manageUserApi.queryUserInfo(id, nickname, city, Convert.toInt(page), Convert.toInt(pagesize));

        // 2.判断查询用户信息结果是否为空 注意：若用户信息为空，则其他表中必不存在该用户
        if (ObjectUtil.isEmpty(userInfoList)) {
            // 为空 直接返回
            return new PageResult(Convert.toInt(page), Convert.toInt(pagesize), 0L, Collections.emptyList());
        }

        // 3.不为空 拼凑UserInfoMapVo对象
        List<UserInfoMapVo> userInfoMapVoList = new ArrayList<>();

        for (UserInfos userInfo : userInfoList) {
            UserInfoMapVo userInfoMapVo = new UserInfoMapVo();
            //根据当前用户id 查询其他表
            User user = manageUserApi.queryUser(userInfo.getUserId());
            Log log = manageUserApi.queryLog(userInfo.getUserId());
            //查询redis中的冻结状态
            String key = Constants.USER_FREEZE + userInfo.getUserId();
            if (redisTemplate.hasKey(key)) {
                userInfoMapVo.setUserStatus("2");
            } else {
                //不存在则说明已解冻
                userInfoMapVo.setUserStatus("1");
            }


            //查询被喜欢人数（粉丝）
            String countBeLiked = userLikeApi.queryFanCount(userInfo.getUserId()).toString();
            if (StringUtils.isNotEmpty(countBeLiked)) {
                //被喜欢人数
                userInfoMapVo.setCountBeLiked(Convert.toInt(countBeLiked));
            }

            //查询喜欢人数
            String countLiked = userLikeApi.queryLikeCount(userInfo.getUserId()).toString();
            if (StringUtils.isNotEmpty(countLiked)) {
                //喜欢人数
                userInfoMapVo.setCountLiked(Convert.toInt(countLiked));
            }

            //查询配对人数（互相喜欢）
            String countMatching = userLikeApi.queryMutualLikeCount(userInfo.getUserId()).toString();
            if (StringUtils.isNotEmpty(countMatching)) {
                //配对人数
                userInfoMapVo.setCountMatching(Convert.toInt(countMatching));
            }

            //当前用户id
            userInfoMapVo.setId(Convert.toInt(userInfo.getUserId()));
            //用户昵称
            userInfoMapVo.setNickname(userInfo.getNickName());
            //账号、手机号
            userInfoMapVo.setMobile(user.getMobile());
            //头像
            userInfoMapVo.setLogo(userInfo.getLogo());
            //头像是否审核通过  1.通过 2.未通过
            userInfoMapVo.setLogoStatus("1");
            //注册城市
            userInfoMapVo.setCity(userInfo.getCity());
            //年龄
            userInfoMapVo.setAge(userInfo.getAge());
            //收入
            userInfoMapVo.setIncome(Convert.toInt(userInfo.getIncome()));
            //性别    重写之后就是很爽！！！！！！
            userInfoMapVo.setSex(userInfo.getSex());
            //注册时间
            userInfoMapVo.setCreated(DateUtil.date(user.getCreated()).getTime());

            //判断日志表中用户是否存在
            if (ObjectUtil.isNull(log)) {
                //最后活跃时间  判断：如果为空，则显示注册时间
                userInfoMapVo.setLastActiveTime(DateUtil.date(user.getCreated()).getTime());
                //最后登录地点  判断：如果为空，则显示注册地点
                userInfoMapVo.setLastLoginLocation(userInfo.getCity());
            } else {
                //最后活跃时间  判断：如果不为空，则显示日志中的最后活跃时间
                userInfoMapVo.setLastActiveTime(DateUtil.date(log.getLogTime()).getTime());
                //最后登录地点  判断：如果不为空，则显示最后登录地点
                userInfoMapVo.setLastLoginLocation(log.getPlace());
            }

            //职业
            userInfoMapVo.setOccupation(userInfo.getIndustry());
            //个性签名
            userInfoMapVo.setPersonalSignature("没有这个字段，太坑了");
            //标签
            userInfoMapVo.setTags(userInfo.getTags());

            //封装完当前用户后，添加到集合中去
            userInfoMapVoList.add(userInfoMapVo);
        }

        Integer count = manageUserApi.counts(id, nickname, city);

        return new PageResult(Convert.toInt(page), Convert.toInt(pagesize), Convert.toLong(count), userInfoMapVoList);
    }

    /**
     * 根据id 查询用户个人详细信息
     *
     * @param userId 要查看的用户id
     * @return
     */
    public UserInfoMapVo queryById(String userId) {

        //Vo对象
        UserInfoMapVo userInfoMapVo = new UserInfoMapVo();

        //1.查询用户信息表
        UserInfos userInfo = manageUserApi.queryUserInfoById(userId);
        //根据当前用户id 查询其他表
        User user = manageUserApi.queryUser(Convert.toLong(userId));
        Log log = manageUserApi.queryLog(Convert.toLong(userId));

        //查询redis中的冻结状态
        String key = Constants.USER_FREEZE + userId;
        if (redisTemplate.hasKey(key)) {
            userInfoMapVo.setUserStatus("2");
        } else {
            //不存在则说明已解冻
            userInfoMapVo.setUserStatus("1");
        }


        //2.1查询被喜欢人数（粉丝）
        Long countBeLiked = userLikeApi.queryFanCount(Convert.toLong(userId));
        if (ObjectUtil.isNotNull(countBeLiked)) {
            //被喜欢人数
            userInfoMapVo.setCountBeLiked(Convert.toInt(countBeLiked));
        }

        //查询喜欢人数
        Long countLiked = userLikeApi.queryLikeCount(Convert.toLong(userId));
        if (ObjectUtil.isNotNull(countLiked)) {
            //喜欢人数
            userInfoMapVo.setCountLiked(Convert.toInt(countLiked));
        }

        //查询配对人数（互相喜欢）
        Long countMatching = userLikeApi.queryMutualLikeCount(Convert.toLong(userId));
        if (ObjectUtil.isNotNull(countMatching)) {
            //配对人数
            userInfoMapVo.setCountMatching(Convert.toInt(countMatching));
        } else {
            userInfoMapVo.setCountMatching(0);
        }

        //当前用户id
        userInfoMapVo.setId(Convert.toInt(userInfo.getUserId()));
        //用户昵称
        userInfoMapVo.setNickname(userInfo.getNickName());
        //账号、手机号
        userInfoMapVo.setMobile(user.getMobile());
        //头像
        userInfoMapVo.setLogo(userInfo.getLogo());
        //头像是否审核通过  1.通过 2.未通过
        userInfoMapVo.setLogoStatus("1");
        //注册城市
        userInfoMapVo.setCity(userInfo.getCity());
        //年龄
        userInfoMapVo.setAge(userInfo.getAge());
        //收入
        userInfoMapVo.setIncome(Convert.toInt(userInfo.getIncome()));
        //性别
        userInfoMapVo.setSex(userInfo.getSex());
        //注册时间
        userInfoMapVo.setCreated(DateUtil.date(user.getCreated()).getTime());

        //判断日志表中用户是否存在
        if (ObjectUtil.isNull(log)) {
            //最后活跃时间  判断：如果为空，则显示注册时间
            userInfoMapVo.setLastActiveTime(DateUtil.date(user.getCreated()).getTime());
            //最后登录地点  判断：如果为空，则显示注册地点
            userInfoMapVo.setLastLoginLocation(userInfo.getCity());
        } else {
            //最后活跃时间  判断：如果不为空，则显示日志中的最后活跃时间
            userInfoMapVo.setLastActiveTime(DateUtil.date(log.getLogTime()).getTime());
            //最后登录地点  判断：如果不为空，则显示最后登录地点
            userInfoMapVo.setLastLoginLocation(log.getPlace());
        }

        //职业
        userInfoMapVo.setOccupation(userInfo.getIndustry());
        //个性签名
        userInfoMapVo.setPersonalSignature("没有这个字段，太坑了(╯‵□′)╯︵┻━┻");
        //标签
        userInfoMapVo.setTags(userInfo.getTags());

        return userInfoMapVo;
    }

    /**
     * 冻结用户操作
     * <p>
     * userid             用户id
     * freezingTime       冻结时间
     * freezingRange        冻结范围
     * reasonsForFreezing  冻结原因
     * frozenRemarks       冻结备注
     *
     * @param params
     * @return
     */
    public Map userFreeze(Map params) {
        //1、构造key
        String userId = params.get("userId").toString();
        String key = Constants.USER_FREEZE + userId;
        //2、构造失效时间
        Integer freezingTime = Integer.valueOf(params.get("freezingTime").toString()); //冻结时间，1为冻结3天，2为冻结7天，3为永久冻结
        int days = 0;
        if (freezingTime == 1) {
            days = 15;
        } else if (freezingTime == 2) {
            days = 30;
        }
        //3、将数据存入redis
        String value = JSONUtil.toJsonStr(params);
        if (days > 0) {
            redisTemplate.opsForValue().set(key, value, days, TimeUnit.SECONDS);
        } else {
            redisTemplate.opsForValue().set(key, value);
        }
        Map retMap = new HashMap();
        retMap.put("message", "冻结成功");
        return retMap;
    }

    /**
     * 解冻用户操作
     * <p>
     * userId             用户ID
     * reasonsForThawing  解冻原因
     *
     * @param params
     * @return
     */
    public Map userUnfreeze(Map params) {
        String userId = params.get("userId").toString();
        String key = Constants.USER_FREEZE + userId;
        //删除redis数据
        redisTemplate.delete(key);
        Map retMap = new HashMap();
        retMap.put("message", "解冻成功");
        return retMap;
    }

    /**
     * 查询指定用户发布的所有视频列表
     *
     * @param page      当前页
     * @param pagesize  显示条数 默认最多10条
     * @param uid       当前查看的用户的id
     * @param sortProp  排序字段
     * @param sortOrder 排序方式 desc 降序   asce 升序
     * @return
     */
    public PageResults findAllVideos(Integer page, Integer pagesize, Long uid, String sortProp, String sortOrder) {

        UserInfo userInfo = userInfoApi.findUserInfoByUserId(uid);
        //分页查询，并排序
        List<VideoInfo> videoInfoList = videoInfoApi.queryVideoInfo(uid, sortProp, sortOrder, page, pagesize);
        //vo对象集合
        ArrayList<VideosVo> voArrayList = new ArrayList<>();

        for (VideoInfo videoInfo : videoInfoList) {
            //拼凑vo
            VideosVo videosVo = new VideosVo();
            //查询单个视频
            Video video = videoApi.findOneByUserId(videoInfo.getVideoId());
            //赋值
            videosVo.setId(Convert.toInt(video.getId()));
            videosVo.setUserId(Convert.toInt(uid));
            videosVo.setNickname(userInfo.getNickName());
            videosVo.setCreateDate(video.getCreated());
            videosVo.setPicUrl(video.getPicUrl());
            videosVo.setVideoUrl(video.getVideoUrl());
            //没有这些字段
            videosVo.setReportCount(0);
            videosVo.setForwardingCount(0);
            // 点赞数
            videosVo.setLikeCount(videoInfo.getLikeCount());
            // 评论数
            videosVo.setCommentCount(videoInfo.getCommentCount());
            //添加到集合中
            voArrayList.add(videosVo);
        }

        List<?> totals = null;
        Long count = Convert.toLong(videoInfoList.size());
        return new PageResults(page, pagesize, count, voArrayList, totals);
    }

    /**
     * 分页查询评论列表
     *
     * @param page
     * @param pageSize
     * @param messageID 审核后的 编号id
     * @param sortProp  排序字段    默认评论人id
     * @param sortOrder 排序方式   默认降序
     * @return
     */
    public PageResult comments(Integer page, Integer pageSize, String messageID, String sortProp,
                               String sortOrder) {
        PublishInfo publishInfo = publishInfoApi.queryPublishInfoById(messageID);

        //根据id查询所有评论
        PageResult pageResult = commentApi.queryCommentListBySort(publishInfo.getPublishId(), page, pageSize, sortProp, sortOrder);
        // 如果没有评论 返回空集合
        if (CollUtil.isEmpty(pageResult.getItems())) {
            return new PageResult();
        }
        // 如果有评论 获取每条评论的评论人userId
        List<Long> userIds = CollUtil.getFieldValues(pageResult.getItems(), "userId", Long.class);
        // 根据userId，查询对应的用户信息userInfo
        Map<Long, UserInfo> userInfoMap = userInfoApi.findUserInfoByUserIds(userIds);

        List<CommentsVo> voList = new ArrayList<>();
        for (Object item : pageResult.getItems()) {
            //得到当前评论对象
            Comment comment = (Comment) item;
            // 拼接VO对象
            CommentsVo commentsVo = new CommentsVo();


            // 评论的id
            commentsVo.setId(comment.getId().toHexString());
            // 评论内容
            commentsVo.setContent(comment.getContent());
            // 评论时间
            commentsVo.setCreateDate(comment.getCreated());

            UserInfo userInfo = userInfoMap.get(comment.getUserId());
            // 评论人昵称
            commentsVo.setNickname(userInfo.getNickName());
            //评论人 id
            commentsVo.setUserId(Convert.toInt(comment.getUserId()));

            voList.add(commentsVo);
        }
        pageResult.setItems(voList);
        return pageResult;
    }


    /**
     * 分页查询登录记录表
     *
     * @param id        用户id
     * @param page      当前页
     * @param pagesize  显示条数
     * @param sortProp  排序字段
     * @param sortOrder 排序方式  ascending 升序  descending  降序
     * @return
     */
    public PageResults queryLogById(Long id, Integer page, Integer pagesize, String sortProp, String sortOrder) {
        PageResults pageResults = logApi.queryLogById(id, page, pagesize, sortProp, sortOrder);
        return pageResults;
    }
}
